home *** CD-ROM | disk | FTP | other *** search
- /* modified by wave to KMLuna for name space protection... */
- /*
- * luna.sl -- surface shader for the moon
- *
- * DESCRIPTION:
- * Makes a surface that looks sort of like Earth's moon. It doesn't really
- * have craters, so it isn't good for closeups. But it's pretty good at about
- * the scale for human naked-eye viewing from earth.
- *
- * AUTHOR:
- * C language version by F. Kenton Musgrave
- * Translation to Shading Language by Larry Gritz.
- *
- * REFERENCES:
- * _Texturing and Modeling: A Procedural Approach_, by David S. Ebert, ed.,
- * F. Kenton Musgrave, Darwyn Peachey, Ken Perlin, and Steven Worley.
- * Academic Press, 1994. ISBN 0-12-228760-6.
- *
- * HISTORY:
- * ??? - original C language version by Ken Musgrave
- * Apr 94 - translation to Shading Language by L. Gritz
- *
- * this file last updated 18 Apr 1994
- */
-
-
- #define snoise(Pt) (2*noise(Pt) - 1)
-
-
- #define DNoise(p) (2*(point noise(p)) - point(1,1,1))
- #define VLNoise(Pt,scale) (snoise(Pt + scale*DNoise(Pt)))
- #define TWOPI (6.28)
-
-
- surface
- KMLuna (float Ka = .5, Kd = 1;
- float lacunarity = 2;
- float octaves = 8;
- float H = .3;
- color highland_color = .7;
- float maria_basecolor = .7, maria_color = .1;
- float arg22 = 1, arg23 = .3;
- float highland_threshold = -0.2;
- float highland_altitude = 0.001, maria_altitude = 0.0004;
- float peak_rad = .0075, inner_rad = .01, rim_rad = .02, outer_rad = .05;
- float peak_ht = 0.005, rim_ht = 0.003;
- float numrays = 8; /* arg10 */
- float rayfade = 1; /* arg11 */
- )
- {
- float radial_dist;
- point PP, PQ;
- float l, a, o, i, omega;
- float chaos;
- color Ct;
- float temp1;
- point vv;
- float uu, ht, freq, scale;
- float lighten;
- point NN;
- float pd; /* pole distance */
- float raydist;
-
- PQ = P;
- PP = transform ("shader", P);
- NN = normalize (N);
- radial_dist = sqrt (xcomp(PP)*xcomp(PP) + ycomp(PP)*ycomp(PP));
- omega = pow (lacunarity, (-.5)-H);
-
- /* bumpy = fBm (PP, omega, lacunarity, octaves); */
- l = 1; o = 1; a = 0;
- for (i = 0; i < octaves; i += 1) {
- a += o * snoise (l * PP);
- l *= lacunarity;
- o *= omega;
- }
- chaos = a;
-
- Ct = Cs;
-
- /* Insure that the crater is in one of the maria */
- temp1 = radial_dist * arg22;
- if (temp1 < 1)
- chaos -= arg23 * (1 - smoothstep (0, 1, temp1));
-
- if (chaos > highland_threshold) {
- PQ += chaos * highland_altitude * NN;
- Ct += highland_color * chaos;
- }
- else {
- PQ += chaos * maria_altitude * NN;
- Ct *= maria_basecolor + maria_color * chaos;
- }
-
-
- /***********************************************************************/
- /* Add crater */
- /* get normalized vector "v" */
- pd = 1-v;
- vv = point (xcomp(PP)/radial_dist, 0, zcomp(PP)/radial_dist);
- lighten = 0;
- if (pd < peak_rad) { /* central peak */
- uu = 1 - pd/peak_rad;
- /* lighten = uu*uu; */
- ht = peak_ht * smoothstep (0, 1, uu);
- }
- else if (pd < inner_rad) { /* crater floor */
- ht = 0;
- }
- else if (pd < rim_rad) { /* inner rim */
- uu = (pd-inner_rad) / (rim_rad - inner_rad);
- lighten = .75*uu;
- ht = rim_ht * smoothstep (0, 1, uu);
- }
- else if (pd < outer_rad) { /* outer rim */
- uu = 1 - (pd-rim_rad) / (outer_rad-rim_rad);
- lighten = .75*uu*uu;
- ht = rim_ht * smoothstep (0, 1, uu*uu);
- }
- else ht = 0;
- PQ += ht * NN;
- lighten *= 0.2;
- Ct += color(lighten,lighten,lighten);
-
- /* Add some noise */
- if (uu > 0) {
- if (pd < peak_rad) { /* if on central peak */
- vv = 5*PP + 3 * vv;
- freq = 1; scale = 1; ht = 0;
- for (i = 0; i < 4; i += 1) {
- ht += scale * snoise (freq * vv);
- freq *= 2; scale *= 0.833;
- }
- /* ht = wrinkled (vv, 2, .833, 4); */
- PQ += 0.0025 * uu*ht * NN;
- }
- else {
- vv = 6*PP + 3 * vv;
- freq = 1; scale = 1; ht = 0;
- for (i = 0; i < 4; i += 1) {
- ht += scale * snoise (freq * vv);
- freq *= 2; scale *= 0.833;
- }
- /* ht = wrinkled (vv, 2, .833, 4); */
- if (radial_dist > rim_rad)
- uu *= uu;
- PQ += 0.0025 * (0.5*uu + 0.5*ht) * NN;
- }
- }
-
-
- /* Make crater rays (PP, arg10, arg11, arg12, arg15, arg24, arg25, radial_dist);, yielding temp1 */
- lighten = 0;
- if (pd >= rim_rad && pd < 0.4) {
- lighten = smoothstep (.15, .5, snoise(62*u));
- raydist = 0.2 + 0.2 * snoise (20 * mod(u+0.022,1));
- lighten *= (1 - smoothstep (raydist-.2, raydist, pd));
- }
- lighten = 0.2 * clamp (lighten, 0, 1);
- Ct += color (lighten, lighten, lighten);
-
-
- /* Recalc normal since we changed P a whole bunch. */
- /* N = normalize (calculatenormal (PQ)); */
-
- /* Shade like matte */
- Oi = 1;
- Ci = Ct * (Ka * ambient() + Kd * diffuse(faceforward(normalize(N),I)));
- }
-
-